import Singlelon from '../Common/Singlelon';
import { BundleConfig } from '../NeedChange/BundleConfig';
import ResMgr from '../Res/ResMgr';
import UIBase from './UIBase';
const { ccclass, property } = cc._decorator;

@ccclass
export default class UIManager extends Singlelon<UIManager>() {
    //用于管理UI界面
    //存UI，打开和关闭UI页面
    // private static _instance: UIManager = null;
    // static get instance() {
    //     if (!this._instance) {
    //         this._instance = new UIManager();
    //         this._instance._init();
    //     }
    //     return this._instance;
    // }
    //存储UI的容器
    private _mapUI: Map<string, UIBase> = new Map();

    //存储UI需要挂载的父节点
    private _mapLayers: Map<string, cc.Node> = new Map();

    //只调用一次，就是初始UIRoot
    protected async _init() {
        //寻找是否有UIRoot节点
        let uiRootN: any = cc.find("Canvas/UIRoot");
        //存储UIRoot的子节点到容器中
        let saveLayers = (uiRootNode: cc.Node) => {
            let children = uiRootNode.children;
            for (let child of children) {
                this._mapLayers.set(child.name, child);
            }
        }
        //没有创建UIRoot节点
        if (!uiRootN) {
            // let uiRootPath = uiPath.UIRoot;
            // if (uiRootPath.length <= 0) {
            //     error("没有配置此节点路径");
            //     return;
            // }
            //获取UIRoot预制体的路径
            let prefab = ResMgr.instance.getRes<cc.Prefab>("UIFramework", "UIRoot");
            if (!prefab) {
                //如果没有获取到资源，就代表资源没有加载过，需要加载
                await ResMgr.instance.getResWithNeed("UIFramework", "UIRoot");
                prefab = ResMgr.instance.getRes<cc.Prefab>("UIFramework", "UIRoot");
            }
            uiRootN = cc.instantiate(prefab);
            uiRootN.parent = cc.find("Canvas");
        }
        saveLayers(uiRootN);
    }

    //打开UI页面
    //UI页面的名字   UI页面需要挂载的节点
    async openUI(uiName: string, bundleName: string, layerName: string = "Normal", ...rest: any[]) {
        if (uiName.length <= 0 || !uiName || bundleName.length <= 0 || !bundleName) {
            cc.error("传入的UI名字有误或者包名传入有误");
            return;
        }
        let ui = this._mapUI.get(uiName);
        if (!ui) {
            //可能获取的是已经加载过的资源，加载获取的资源会存储在包中，直接从包中获取即可
            //如果是没有加载过的资源就需要进行加载
            let prefab = ResMgr.instance.getRes<cc.Prefab>(bundleName, uiName);
            if (!prefab) {
                await ResMgr.instance.getResWithNeed<cc.Prefab>(bundleName, uiName);
                prefab = ResMgr.instance.getRes<cc.Prefab>(bundleName, uiName);
            }
            let uiNode: any = cc.instantiate(prefab);
            let parentNode = this._mapLayers.get(layerName);
            if (!parentNode) {
                cc.error(layerName + "未存储");
                return;
            }
            uiNode.parent = parentNode;
            //将ui页面存入容器中
            ui = uiNode.getComponent(UIBase);
            this._mapUI.set(uiName, ui);
            ui.uiName = uiName;
            //UI第一次打开时，需要将这个需要关注的UI存入到容器中
            ui.init.apply(ui, rest);
            //resolve传入的资源会自动传入到then中
            // await ResMgr.instance.getResWithNeed<Prefab>(bundleName, uiName).then((prefab: Prefab) => {
            //     if (!prefab) {
            //         error(uiName + "的预制体没有获取到");
            //         return;
            //     }
            //     uiNode = instantiate(prefab);
            //     let parentNode = this._mapLayers.get(layerName)
            //     if (!parentNode) {
            //         error(layerName + "未存储");
            //         return;
            //     }
            //     uiNode.parent = parentNode;
            //     //将ui页面存入容器中
            //     ui = uiNode.getComponent(UIBase);
            //     this._mapUI.set(uiName, ui);
            //     ui.uiName = uiName;
            //     //UI第一次打开时，需要将这个需要关注的UI存入到容器中
            //     ui.init.apply(ui, rest);
            // });
        }
        ui.open.apply(ui, rest);
    }


    //关闭UI页面
    closeUI(uiName: string, isDestroy: boolean, ...rest: any[]) {
        if (uiName.length <= 0) {
            return;
        }
        let ui = this._mapUI.get(uiName);
        if (!ui) {
            return;
        }
        let args = Array.prototype.slice.call(arguments, 1);
        ui.close.apply(ui, args);
        this._mapUI.delete(uiName);
    }

    //发送消息
    /**
     * 
     * @param msgName 消息的名字
     * @param uiName UI名
     * @param rest 剩余参数
     */
    sendMsg(msgName: string, uiName: string, ...rest: any[]) {
        //如果没有传入UI的名字，就给所有UI发送消息
        if (!uiName || uiName.length <= 0) {
            for (let ui of Array.from(this._mapUI.values())) {
                let cb = ui[msgName];
                if (!cb) {
                    ui.handleMsg.apply(ui, rest);
                    continue;
                }
                cb.apply(ui, rest);
            }
            return;
        }
        //如果传了UI名字，就对具体的UI发送消息
        let ui = this._mapUI.get(uiName);
        if (!ui) {
            cc.error(`所传${uiName}名字有误`);
            return;
        }
        let cb = ui[msgName];
        if (!cb) {
            cc.error("默认消息不存在");
            return;
        }
        cb.apply(ui, rest);
    }

}


